package com.world.rickcloudendpoint;

import io.netty.util.internal.StringUtil;
import lombok.extern.log4j.Log4j2;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.DefaultApplicationArguments;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.util.StringUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
import java.util.Properties;

/**
 * @description: 项目启动主人口
 * @author: jlsong
 * @date: 2021/12/04 15:55:27
 * @version: 1.0
 */
@Log4j2
public class BusinessApplication {

    private static final String appConfFileName = "application.properties";

    private SpringApplication application;

    public BusinessApplication(Class<?>[] primarySource) {
        application = new SpringApplication(primarySource);
//        Set<ApplicationListener<?>> listeners = this.application.getListeners();
//        this.application.setListeners(listeners);
    }


    /**
     * 校验参数
     *
     * @param args 命令行参数
     */
    private void checkApplicationConfiguration(String... args) {
        Properties properties = new Properties();

        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        List<String> configLocations = applicationArguments.getOptionValues("spring.config.location");

        // 配置路径以绝对路径开始，则不拼接当前工程路径，否则拼接当前工程路径
        if (configLocations != null && configLocations.size() > 0) {
            String filePath = configLocations.get(0);
            String absolutePath = filePath;
            String projectPath = System.getProperty("user.dir");
            if (!projectPath.startsWith("/")) {
                absolutePath = projectPath + File.separator + filePath;
            }
            log.info(String.format("load %s of this URL is %s", appConfFileName, absolutePath));
            try {
                BufferedReader bufferedReader = new BufferedReader(new FileReader(absolutePath));
                properties.load(bufferedReader);
            } catch (IOException e) {
                log.error(String.format("can't load %s from URL %s!",appConfFileName, absolutePath));
                System.exit(-1);
            }

        } else {
            log.info(String.format("load %s of this URL is %s", "classpath", appConfFileName));
            try {
                properties.load(this.getClass().getResourceAsStream(String.format("/%s", appConfFileName)));
            } catch (IOException e) {
                log.error(String.format("can't load %s from classpath(not filepath)!", appConfFileName));
                System.exit(-1);
            }
        }

        String applicationName = properties.getProperty("spring.application.name");
        if (StringUtil.isNullOrEmpty(applicationName)) {
            log.error(String.format(
                    "the file of the %s must be contain the rootPath of spring.application.name and this value can not be null and the file charset must be UTF8 NO BOM.", appConfFileName));
            System.exit(-1);
        }
    }


    public BusinessApplication(Class<?> primarySource) {
        this(new Class<?>[]{primarySource});
    }

    public ConfigurableApplicationContext run(String... args) {
        // 校验配置参数
        checkApplicationConfiguration(args);

        return application.run(args);
    }

    public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
        return run(new Class<?>[]{primarySource}, args);
    }

    public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
        return new BusinessApplication(primarySources).run(args);
    }
}
